package tcln.gxtx.client.widget.grid.renderer.widget;

import tcln.gxtx.client.widget.treegrid.AbstractTreeGrid;
import tcln.gxtx.client.widget.treegrid.model.AbstractTreeModel;

import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ComponentPlugin;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;

/**
 * A common interface for a normal grid cell renderer supporting widgets.
 * 
 * @param <M>
 *            Model data type.
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public interface WidgetGridCellRenderer<M extends AbstractTreeModel> extends GridCellRenderer<M>, ComponentPlugin {

    /**
     * {@inheritDoc}
     */
    @Override
    Object render(M model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<M> store,
            Grid<M> grid);

    /**
     * Checks if method {@link #init(com.extjs.gxt.ui.client.widget.Component)} has been called.
     * 
     * @return <code>true</code> if method {@link #init(com.extjs.gxt.ui.client.widget.Component)} has been called at
     *         least once. Otherwise, return <code>false</code>.
     */
    boolean isInitialized();

    /**
     * Sets the owner treegrid for this renderer to specify things such as row height.
     * <p>
     * This method would be called by {@link AbstractTreeGrid} when it creates column renderers.
     * 
     * @param ownerTree
     */
    void setOwnerTree(AbstractTreeGrid<M> ownerTree);

    /**
     * Handles {@link com.extjs.gxt.ui.client.event.Events#CellMouseDown} event.
     * 
     * @param event
     */
    void handleCellMouseDown(GridEvent<M> event);

    /**
     * Checks if this renderer is a part of a contextual renderer, which supports 'render-by-context'.
     * 
     * @return
     */
    boolean isInContextualRenderer();

    /**
     * Adds a listener for 'change' event while editing in this renderer.
     * 
     * @param listener
     */
    void addChangeListener(Listener<GridEvent<M>> listener);

    /**
     * Returns the column holding this renderer.
     * 
     * @return Column configuration or <code>null</code> if this renderer hasn't been set to any column.
     */
    ColumnConfig getOwnerColumn();
}
